<?php
/**
 * Created by PhpStorm
 * User: Jhinwy
 * Date: 4/18/24
 * Time: 2:27 PM
 */

namespace app\common\service\media;

use app\common\model\media\Media;
use app\common\model\media_account\MediaAccount;
use app\common\model\media_account\MediaAuth;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;
use GuzzleHttp\RequestOptions;
use think\facade\Log;

class UcService
{

    protected $config;
    protected $username;
    protected $password;
    protected $token;

    protected $headers = [
        'Content-Type' => 'application/json',
    ];

    public function __construct($authId)
    {
        $mediaAuth      = MediaAuth::where('id', $authId)->findOrEmpty();
        $this->config   = config('media.uc') ?? [];
        $this->username = $mediaAuth->username ?? '';
        $this->password = $mediaAuth->password ?? '';
        $this->token    = $mediaAuth->token ?? '';
    }


    /**
     * 获取UC广告主账户信息
     *
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getAdAccount($authId)
    {
        try {
            $fields   = [
                'header' => [
                    'username' => $this->username,
                    'password' => $this->password,
                    'token'    => $this->token
                ]
            ];
            $client   = new Client();
            $response = $client->request(
                'POST',
                $this->config['advertiser_api'] ?? '',
                [
                    'headers'            => $this->headers,
                    'timeout'            => 60,
                    RequestOptions::JSON => $fields
                ]
            );
            if ($response->getStatusCode() !== 200) {
                throw new \Exception('请求失败');
            }
            $contents = $response->getBody()->getContents();
            $data     = json_decode($contents, true);
            if (($data['header']['status'] ?? -1) != 0) {
                throw new \Exception($data['header']['desc'] ?? '');
            }
            if (!$accounts = $data['body']['childrenAccounts'] ?? []) {
                Log::error('获取广告主信息失败：' . json_encode($data));
                throw new \Exception('广告主信息不存在');
            }
            $insertData = [];
            foreach ($accounts as $account) {
                if (MediaAccount::where('advertiser_id', $account['id'] ?? 0)->where('media_id', Media::SOURCE_UC)->findOrEmpty()->isEmpty()) {
                    $insertData[] = [
                        'media_id'        => Media::SOURCE_UC,
                        'media_auth_id'   => $authId,
                        'advertiser_id'   => $account['id'] ?? 0,
                        'advertiser_name' => $account['name'] ?? '',
                        'company'         => $account['companyName'] ?? '',
                        'create_time'     => time(),
                        'update_time'     => time()
                    ];
                }
            }
            MediaAccount::insertAll($insertData);

            return true;
        } catch (\Exception $exception) {
            Log::error('获取UC授权账户失败：' . $exception->getMessage());

            return false;
        }
    }


    /**
     * 获取成本报告
     *
     * @param $nickname
     * @param $linkId
     * @param $date
     * @return \Illuminate\Support\TLastDefault|\Illuminate\Support\TValue|int|mixed
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getAdvertiserReport($nickname, $date)
    {
        try {
            $header = [
                'username' => trim($this->username),
                'password' => trim($this->password),
                'token'    => trim($this->token),
                'target'   => trim($nickname)
            ];
            $fields = [
                'header' => $header,
                'body'   => [
                    'reportType' => [
                        'startDate'     => (int)$date,
                        'endDate'       => (int)$date,
                        'adReportType'  => 1,
                        'aggregateType' => 1,
                        'reportColumns' => ['consume']
                    ]
                ]
            ];

            $client = new Client(['timeout' => 3.0]);

            $response = $client->request(
                'POST',
                $this->config['report_api'] ?? '',
                [
                    'headers'            => $this->headers,
                    'timeout'            => 60,
                    RequestOptions::JSON => $fields
                ]
            );

            if ($response->getStatusCode() !== 200) {
                throw new \Exception('请求失败');
            }
            $contents = $response->getBody()->getContents();

            $data = json_decode($contents, true);
            if (!$taskId = $data['body']['taskId'] ?? '') {
                Log::error('获取UC账户成本失败', $data);

                return 0;
            }

            // 下载报表文件
            $dFields  = ['header' => $header, 'body' => ['taskId' => $taskId]];
            $filename = $this->getFile();
            $resource = Utils::tryFopen($filename, 'w');
            $client->request(
                'POST',
                config('media.uc.download_report_api') ?? '',
                [
                    RequestOptions::JSON  => $dFields,
                    RequestOptions::DELAY => 5000,
                    'sink'                => $resource,
                ]
            );

            // 读取报表成本
            $contents  = explode(',', file_get_contents($filename));
            $costMoney = collect($contents)->map(function ($item) {
                return str_replace("\r\n", '', $item);
            })->last();

            // 删除文件，更新成本
            unlink($filename);
            if (!is_numeric($costMoney)) {

                return 0;
            }

            return $costMoney;
        } catch (\Exception $exception) {

            Log::error('获取UC成本报表失败：' . $exception->getMessage());

            return 0;
        }
    }


    private function getFile()
    {
        return $this->getFilePath() . md5(time()) . '.csv';
    }


    /**
     * 获取文件路径
     *
     * @return string
     */
    private function getFilePath()
    {
        $absolutePath = public_path('resource/');
        if (!is_dir($absolutePath)) {
            mkdir($absolutePath, 0777, true);
        }

        return $absolutePath;
    }
}
